<template>
  <div
      ref="scrollElement"
      class="scroll-fade-section"
      :style="{
      opacity: opacity,
      transform: transformStyle,
      transitionDelay: delay + 's'
    }"
  >
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: "ScrollFadeIn",
  props: {
    direction: {
      type: String,
      default: "right" // 可选：right, left, top, bottom
    },
    distance: {
      type: Number,
      default: 60
    },
    delay: {
      type: Number,
      default: 0 // 单位秒
    },
    triggerRatio: {
      type: Number,
      default: 0.5 // 元素到视口高度 40% 时透明度为1
    }
  },
  data() {
    return {
      opacity: 0,
      transformStyle: "",
      throttledScrollHandler: null
    };
  },
  mounted() {
    this.throttledScrollHandler = this.throttle(this.handleScroll, 16); // ~60fps
    window.addEventListener("scroll", this.throttledScrollHandler, { passive: true });
    this.handleScroll(); // 初始执行一次
  },
  beforeDestroy() {
    window.removeEventListener("scroll", this.throttledScrollHandler);
  },
  methods: {
    handleScroll() {
      const el = this.$refs.scrollElement;
      const rect = el.getBoundingClientRect();
      const windowHeight = window.innerHeight;

      // 计算滑动进度
      const triggerPoint = windowHeight * this.triggerRatio;
      const progress = 1 - Math.min(Math.max((rect.top - triggerPoint) / (windowHeight - triggerPoint), 0), 1);

      const opacity = Math.max(0, Math.min(progress, 1));
      const offset = (1 - opacity) * this.distance;

      let transform = "";
      switch (this.direction) {
        case "left":
          transform = `translateX(${-offset}px)`;
          break;
        case "right":
          transform = `translateX(${offset}px)`;
          break;
        case "top":
          transform = `translateY(${-offset}px)`;
          break;
        case "bottom":
          transform = `translateY(${offset}px)`;
          break;
        default:
          transform = `translateX(${offset}px)`;
      }

      this.opacity = opacity;
      this.transformStyle = transform;
    },

    throttle(fn, delay) {
      let lastCall = 0;
      return function (...args) {
        const now = new Date().getTime();
        if (now - lastCall >= delay) {
          lastCall = now;
          fn.apply(this, args);
        }
      };
    }
  }
};
</script>

<style scoped>
.scroll-fade-section {
  transition: opacity 0.4s ease-out, transform 0.4s ease-out;
  will-change: opacity, transform;
}
</style>
